package com.game.grid.GameStates;

import javax.microedition.khronos.opengles.GL10;
import android.graphics.Point;
import android.view.MotionEvent;

import com.game.grid.Box;
import com.game.grid.GUIRenderer;
import com.game.grid.GridManager;
import com.game.grid.MazeManager;
import com.game.grid.ParticleSystem;
import com.game.grid.Player;
import com.game.grid.R;
import com.mcodesal.framework.GameEngine;
import com.mcodesal.framework.GameState;
import com.mcodesal.framework.audio.SoundManager;

public class Game extends GameState{
	
	private ParticleSystem mParticleSystem;
	
	private Player player = new Player(0, 0, 30);
	
	private MazeManager mazeManager;
	private GridManager gridManager;
	
	//array sizes 
	public static final int LARGEST_BOX_ARRAY = 3;
	public static final int LARGE_BOX_ARRAY = 3;
	public static final int SMALL_BOX_ARRAY = 4;
	public static final int SMALLEST_BOX_ARRAY = 5;
	
	//player Starting Location  is scaled by the starting size of the screen
	private int startingX;
	private int startingY;
	
	//screen size when game is initialized.
	private int screenSizeX;
	private int screenSizeY;
	
	//starting speed for boxes falling
	public int speedMult = 1;
	
	
	//player location
	private Point playerPos;  //the current location of the player
	
	private long mStartTime = -1;
	private int mElapsedTime = 0;
	private long mLastTime = -1;
	
	//boolean state flags.
	private boolean gameStarted = false;
	public boolean gamePaused = true;
	public boolean drawing = false;

	
	private GUIRenderer guiRenderer;
	
	public Game(GameEngine engine) {
		super(engine);
		guiRenderer = new GUIRenderer();
		mParticleSystem = new ParticleSystem();
        mazeManager = new MazeManager();
        gridManager = new GridManager();
        SoundManager.getInstance();
        SoundManager.initSounds(engine.context);
        SoundManager.addBGM(R.raw.game_music_loop);
        SoundManager.addSound(R.raw.game_music_loop);
        SoundManager.addSound(R.raw.wall_hit_sound);
        SoundManager.addSound(R.raw.checkpoint_sound);
        //SoundManager.playLoopedSound(R.raw.game_music_loop, 1);
    	//SoundManager.playBGM();
    	
    	//initializing player position and box.
    	playerPos = new Point(startingX, startingY);
    	
    	
	}
	@Override
    public void handleTouchEvent(MotionEvent event)
    {	
		//we only move the player if the person touches the screen within 50 pixels of the
		//player's location.
		double temp = Math.hypot(event.getX() - (playerPos.x- player.size/2),event.getY() - playerPos.y - player.size/2);
		if(temp < 100) {
			playerPos.x = (int)event.getX();
			playerPos.y = (int)event.getY() - player.size/2;
			player.setLoc(playerPos.x, playerPos.y);
			
		}
				
    }
    
    
	
	/*
	 * the update function, is used to calculate the time elapsed.
	 */
	public void update(long gameTime) {
		if(!gamePaused) {
			if(mStartTime == -1) {
				mStartTime = gameTime;
			}
			mElapsedTime = (int)((gameTime - mStartTime)/1000);
			player.update(gameTime);
			mazeManager.checkSize(mElapsedTime);
			mazeManager.playerCollision(playerPos);
			mazeManager.moveBoxes(speedMult, gameTime);
			mazeManager.update(gameTime);
			gridManager.update(speedMult, gameTime);
			
	    	float sizeChangeYPosition = mazeManager.checkBoxesOnScreen();
	    	if(sizeChangeYPosition != -10000) {
	    		mParticleSystem.setPosition(0, sizeChangeYPosition-16, 0);
	    	}
	    	if(mLastTime == -1) {
				mLastTime = gameTime;
			}
			if(gameTime - mLastTime  > 30) {
				if(mParticleSystem.y > -30 || mParticleSystem.y < 500) {
		    		mParticleSystem.setPosition(0, mParticleSystem.y+(speedMult*4), 0);
		    		mParticleSystem.update();
		    	}
				mLastTime = gameTime;
			}
	    	
		}
		
	}
	
	@Override
    public void initialize(GL10 gl, int w, int h) {
        
        guiRenderer.initialize(gl, w, h);
        mazeManager.initialize(w,h);
        mParticleSystem.initialize(w, h);
        
        startingX = w/2;
		startingY = h - (mazeManager.curBoxSize/2) - 50;
		
		playerPos.x = startingX;
		playerPos.y = startingY;
		
		//also use this opportunity to initialize some variables/zero the clock
		gamePaused = false;
		
    }
    
    @Override
    public void render(GL10 gl) {
		
    	
		//Rendering Code
    	gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        
        //Render background grid
        gridManager.draw(gl);
        
        //Render box path
        mazeManager.draw(gl);
    	
        //Update and render player
    	player.setLoc(playerPos.x, playerPos.y);
    	player.draw(gl);
    	
    	if(mParticleSystem.y > -30 || mParticleSystem.y < 500) {
    		mParticleSystem.draw(gl);
    	}
    	//Render GUI on top of everything
    	guiRenderer.mScoreValue.setValue(mElapsedTime);
    	guiRenderer.draw(gl);
    }

}
